<?php

namespace Common\Model;

use Common\Model\AiModel;
use Think\Exception;

class HospitalModel extends AiModel
{

    private function _addLevel($hospital_list)
    {
        $arr = array(
            '0' => '',
            '1' => '一级',
            '2' => '二级',
            '3' => '三级',
            '4' => '三级特',
        );

        array_walk($hospital_list, function (&$hospital) use ($arr) {
            $ksys = array_keys($arr, $hospital['hospital_level']);
            $hospital['level'] = (string)$ksys[0];
        });

        return $hospital_list;
    }

    private function _addScore($hostipal_list)
    {
        $hospitalScore = new HospitalScoreModel();
        array_walk($hostipal_list, function (&$hospital) use ($hospitalScore) {
            $score = $hospitalScore->pullHospitalScore((int)$hospital['id']);
            $hospital['score'] = $score['max'];

            if ($score['max'] == 0 || $score['max']) {
                $hospital['eva'] = '';
            } else {
                $hospital['eva'] = $score['max'] . '%的用户对 “' . $score['ser'] . '” 满意';
            }

        });

        return $hostipal_list;
    }

    private function _addDis($hostipal_list)
    {
        $lng = I('lng', '', 'trim');
        $lat = I('lat', '', 'trim');

        array_walk($hostipal_list, function (&$hospital) use ($lng, $lat) {
            if ($lng == '' || $lat == '') {
                $hospital['dis'] = '';
            } else {
                $hospital['dis'] = (string)round(getDistance($lat, $lng, $hospital['lat'], $hospital['lng']) / 1000, 1);
            }
        });

        return $hostipal_list;
    }

    private function _disSort($hospital_list)
    {
        $sort = array(
            'direction' => 'SORT_ASC', //排序顺序标志 SORT_DESC 降序；SORT_ASC 升序
            'field' => 'dis',       //排序字段
        );

        $arrSort = array();
        foreach ($hospital_list AS $uniqid => $row) {
            foreach ($row AS $key => $value) {
                $arrSort[$key][$uniqid] = $value;
            }
        }

        if ($sort['direction']) {
            array_multisort($arrSort[$sort['field']], constant($sort['direction']), $hospital_list);
        }

        return $hospital_list;
    }

    private function _evaSort($hospital_list)
    {
        $sort = array(
            'direction' => 'SORT_DESC', //排序顺序标志 SORT_DESC 降序；SORT_ASC 升序
            'field' => 'score',       //排序字段
        );

        $arrSort = array();
        foreach ($hospital_list AS $uniqid => $row) {
            foreach ($row AS $key => $value) {
                $arrSort[$key][$uniqid] = $value;
            }
        }

        if ($sort['direction']) {
            array_multisort($arrSort[$sort['field']], constant($sort['direction']), $hospital_list);
        }

        return $hospital_list;
    }

    private function _levelSort($hospital_list)
    {
        $sort = array(
            'direction' => 'SORT_DESC', //排序顺序标志 SORT_DESC 降序；SORT_ASC 升序
            'field' => 'level',       //排序字段
        );

        $arrSort = array();
        foreach ($hospital_list AS $uniqid => $row) {
            foreach ($row AS $key => $value) {
                $arrSort[$key][$uniqid] = $value;
            }
        }

        if ($sort['direction']) {
            array_multisort($arrSort[$sort['field']], constant($sort['direction']), $hospital_list);
        }

        return $hospital_list;
    }

    private function _getHospitalList($where = null)
    {
        $keyword = I('keyword', '', 'trim');

        if (is_null($where) || $where == '') {
            if ($keyword != '') $where = array('name' => array('like', "%{$keyword}%"));
        } else {
            if ($keyword != '') $where['name'] = array('like', "%{$keyword}%");
        }

        $hospital_list = $this->field('id, name, image, hospital_level, lng, lat, treat_id')->where($where)->order('ord DESC')->select();

        if (is_null($hospital_list)) return array();

        $hospitalTreat = new HospitalTreatModel();
        array_walk($hospital_list, function (&$hospital) use ($hospitalTreat) {
            $treat = $hospitalTreat->getTreatById((int)$hospital['treat_id']);
            $hospital['image'] = initImageLocal($hospital['image']);
            $hospital['treat'] = is_null($treat) ? '' : $treat['name'];
            $hospital['reserve'] = '0';
        });

        $hospital_list = $this->_addScore($hospital_list);
        $hospital_list = $this->_addDis($hospital_list);
        $hospital_list = $this->_addLevel($hospital_list);

        return $hospital_list;
    }

    public function hospitalList($condition = '')
    {
        $hospital_list = $this->_getHospitalList();
        if ($condition != '') {
            $fun = '_' . $condition . 'Sort';
            $hospital_list = $this->$fun($hospital_list);
        }

        $result = is_null($hospital_list) ? array() : $hospital_list;
        return $result;
    }

    private function _limitHospitalList($limit, $lng, $lat)
    {
        $new_hospital_list = array();

        $mongo = get_mongo_obj('Location');
        if ($mongo === false) {
            $m_limit = $limit * 1000;

            $hospital_list = $this->_getHospitalList();
            $count = (string)count($hospital_list);
            if ($count == 0) return $new_hospital_list;

            $new_hospital_list = array();
            foreach ($hospital_list as &$hospital) {
                if ($hospital['dis'] <= $limit) {
                    $new_hospital_list[] = $hospital;
                }
            }

            $new_hospital_list = $this->_disSort($new_hospital_list);
        } else {
            try {
                $maxDistance = $limit / 111.12;
                $sql = 'db.runCommand({geoNear:"jj_location",near:[' . $lng . ',' . $lat . '],maxDistance:' . $maxDistance . ',query:{cate:"hospital"}})';
                $result = $mongo->mongoCode($sql);

                $hospitals = $result['results'];

                if ($hospitals != array()) {
                    $hospital = new HospitalModel();
                    $hospitalTreat = new HospitalTreatModel();

                    foreach ($hospitals as $v) {
                        $h_info = $hospital->field('name, image, hospital_level, treat_id')->where(array('id' => (int)$v['obj']['id']))->find();
                        $treat = $hospitalTreat->getTreatById((int)$h_info['treat_id']);

                        $new_hospital_list[] = array(
                            'id' => $v['obj']['id'],
                            'lng' => (string)$v['obj']['loc'][0],
                            'lat' => (string)$v['obj']['loc'][1],
                            'dis' => (string)round($v['dis'] * 100, 1),
                            'image' => initImageLocal($h_info['image']),
                            'treat' => is_null($treat) ? '' : $treat['name'],
                            'reserve' => '0',
                            'name' => $h_info['name'],
                            'treat_id' => $h_info['treat_id'],
                            'hospital_level' => $h_info['hospital_level'],
                        );

                    }

                    $new_hospital_list = $this->_addScore($new_hospital_list);
                    $new_hospital_list = $this->_addLevel($new_hospital_list);
                }
            } catch (Exception $e) {
                $m_limit = $limit * 1000;

                $hospital_list = $this->_getHospitalList();
                $count = (string)count($hospital_list);
                if ($count == 0) return $new_hospital_list;

                $new_hospital_list = array();
                foreach ($hospital_list as &$hospital) {
                    if ($hospital['dis'] <= $limit) {
                        $new_hospital_list[] = $hospital;
                    }
                }

                $new_hospital_list = $this->_disSort($new_hospital_list);
            }
        }

        return $new_hospital_list;
    }

    public function limitHospitalList($lng, $lat)
    {
        $limit_list = array(1, 3, 5, 10);

        $data = array(
            'limit' => 1,
            'count' => '0',
            'list' => array()
        );

        for ($i = 0; $i < 5; $i++) {
            $data['limit'] = (string)$limit_list[$i];
            $new_hospital_list = $this->_limitHospitalList($limit_list[$i], $lng, $lat);
            $count = (string)count($new_hospital_list);
            if ($count >= 10) {
                break;
            }
        }

        $data['count'] = $count;
        $data['list'] = $new_hospital_list;

        return $data;
    }

    function hospitalListByTreat($treat_id)
    {
        $where = array('treat_id' => $treat_id);
        $hospital_list = $this->_getHospitalList($where);
        return $hospital_list;
    }

    function hospitalInfo($id)
    {
        $result = $this->where(array('id' => $id))->find();

        if (is_null($result)) return false;

        $commArea = new CommAreaModel();
//        $userDoctor = new UserDoctorModel();
        $hospitalTreat = new HospitalTreatModel();

        $result['province'] = $commArea->getAreaName($result['province_id']);
        $result['city'] = $commArea->getAreaName($result['city_id']);
        $result['area'] = $commArea->getAreaName($result['area_id']);

        $result['province'] = empty($result['province']) ? '' : $result['province'];
        $result['city'] = empty($result['city']) ? '' : $result['city'];
        $result['area'] = empty($result['area']) ? '' : $result['area'];

        $result['image'] = initImageLocal($result['image']);
//        $result['count'] = $userDoctor->where(array('hospital_id' => $id, 'is_show' => 1))->count();
        $result['count'] = $this->_hospitalDoctorCount($id);

        $treat = $hospitalTreat->getTreatById((int)$result['treat_id']);
        $result['treat'] = is_null($treat) ? '' : $treat['name'];
        $result['doctor_online'] = $this->isHasDoctorOnline($id);
        $result['is_res'] = $result['is_appoint'];

        unset($result['province_id']);
        unset($result['city_id']);
        unset($result['area_id']);

        $hospitalScore = new HospitalScoreModel();
        $score_info = $hospitalScore->pullHospitalScore($id);
        if ($score_info['max'] == 0) {
            $result['score'] = '';
        } else {
            $result['score'] = $score_info['max'] . '%的患者对' . $score_info['ser'] . '满意';
        }

        return $result;
    }

    private function _hospitalDoctorCount($hospital_id) {
        $sql = "SELECT COUNT(*) as c FROM jj_user_doctor as a, jj_user_expand as b WHERE a.id = b.id AND a.is_show = 1 AND b.hospital_id = {$hospital_id}";
        $result = M()->query($sql);
        return $result[0]['c'];
    }

    function getHospitalName($id)
    {
        $name = $this->where(array('id' => $id))->getField('name');
        if (is_null($name)) $name = '';
        return $name;
    }

    function getHospitalAliases($id)
    {
        $aliases = $this->where(array('id' => $id))->getField('aliases');
        return $aliases;
    }

    function transfer($user_id, $hospital_id)
    {
        #$h_id = D('UserGravide')->where(array('id' => $user_id))->getField('hospital_id');
        $h_id = D('User')->getUserAttr($user_id,'hospital_id');
        if ($h_id == $hospital_id) return '无需转院';

        $d_count = D('DatumAudit')->where(array('passive_user_id' => $user_id))->save(array('hospital_id' => $hospital_id));
        $u_count = D('UserGravide')->save(array('id' => $user_id, 'hospital_id' => $hospital_id));

        if ($d_count !== false && $u_count !== false) {
            $data = array(
                'doctor_id' => UID,
                'gravide_id' => $user_id,
                'hospital_id' => $hospital_id,
                'add_time' => ADD_TIME
            );

            D('TransferLog')->add($data);
            return '转院成功';
        } else {
            return '转院失败';
        }
    }

    function latelyHospitalList($location_list)
    {
        $hospital_localtion_list = S('hospital_list');
        if (empty($hospital_localtion_list)) {
            $hospital_localtion_list = $this->select();
            S('hospital_list', $hospital_localtion_list);
        }

        if ($hospital_localtion_list == NULL) return array();

        foreach ($hospital_localtion_list as $k => $v) {
            $d = getDistance($location_list[1], $location_list[0], $v['lat'], $v['lng']);
            $hospital_localtion_list[$k]['distance'] = bcdiv($d, '1000', 2);
            $hospital_localtion_list[$k]['image'] = initImageLocal($v['image']);

            unset($hospital_localtion_list[$k]['introduction']);
            $distance[$k] = $d;
        }
        array_multisort($distance, $hospital_localtion_list);

        $data = $this->arrayPage($hospital_localtion_list);

        // 获取最高评分项以及人数
        foreach ($data as $k => $v) {
            $score_list = D('HospitalScore')->pullHospitalScore((int)$v['id']);
            $data[$k]['score_sum'] = $score_list['sum'];
            $data[$k]['score_max'] = $score_list['max'];
            $data[$k]['score_ser'] = ($score_list['sum'] == 0 || $score_list['max'] == 0) ? '' : $score_list['ser'];
        }

        return $data;
    }

    function latelyGoTheHospitalList($user_id)
    {
        $clinic_ids = D('ClinicLetter')->field('clinic_id')->where(array('user_id' => $user_id))->select();
        $clinic_ids = dimensionality_reduction($clinic_ids, 'clinic_id');
        $clinic_ids = array_unique($clinic_ids);

        if (count($clinic_ids) == 0) return array();

        $sql = "SELECT user_id FROM jj_clinic WHERE id IN (" . implode(',', $clinic_ids) . ")";
        $user_ids = M()->query($sql);
        $user_ids = dimensionality_reduction($user_ids, 'user_id');
        $sql = '';

        if (count($user_ids) == 0) return array();

//        $sql = "SELECT hospital_id FROM jj_user_doctor WHERE id IN (" . implode(',', $user_ids) . ")";
        $sql = "SELECT hospital_id FROM jj_user_expand WHERE id IN (" . implode(',', $user_ids) . ")";
        $hospital_ids = M()->query($sql);
        $hospital_ids = dimensionality_reduction($hospital_ids, 'hospital_id');
        $sql = '';

        if (count($hospital_ids) == 0) return array();

        $where = "id IN (" . implode(',', $hospital_ids) . ")";
        $result = $this->field('id, name, image')->where($where)->select();

        if (count($result) == 0) return array();

        $data = $this->arrayPage($result);
        foreach ($data as $k => $v) {
            $score_list = D('HospitalScore')->pullHospitalScore((int)$v['id']);
            $data[$k]['image'] = initImageLocal($v['image']);
            $data[$k]['max'] = $score_list['max'];
            $data[$k]['ser'] = $score_list['max'] == 0 ? '' : $score_list['ser'];
        }

        return $data;
    }

    function findHospitalList($keyword, $location_list)
    {
        $hospital_localtion_list = S('hospital_list');
        if (empty($hospital_localtion_list)) {
            $hospital_localtion_list = $this->select();
            S('hospital_list', $hospital_localtion_list);
        }

        if ($hospital_localtion_list == NULL) return array();

        $result = arrayLikeSearch($hospital_localtion_list, $keyword, 'name');

        foreach ($result as $k => $v) {
            $d = getDistance($location_list[1], $location_list[0], $v['lat'], $v['lng']);
            $result[$k]['distance'] = bcdiv($d, '1000', 2);
            $result[$k]['image'] = initImageLocal($v['image']);
            $distance[$k] = $d;
        }
        array_multisort($distance, $result);

        $data = $this->arrayPage($result);

        // 获取最高评分项以及人数
        foreach ($data as $k => $v) {
            $score_list = D('HospitalScore')->pullHospitalScore((int)$v['id']);
            $data[$k]['score_sum'] = $score_list['sum'];
            $data[$k]['score_max'] = $score_list['max'];
            $data[$k]['score_ser'] = ($score_list['sum'] == 0 || $score_list['max'] == 0) ? '' : $score_list['ser'];
        }

        return $data;
    }

    function arrayPage($data)
    {
        $page_size = 10;
        $nowPage = isset($_REQUEST['p']) ? $_REQUEST['p'] : 1;
        $p = ($nowPage - 1) * $page_size;
        $data = array_slice($data, $p, $page_size);

        return $data;
    }

    public function isHasDoctorOnline($hospital_id)
    {
        $sql = "SELECT b.id FROM jj_user_doctor as a, jj_user as b, jj_user_expand as c WHERE a.id = b.id AND b.id = c.id AND a.is_show=1 AND c.hospital_id = {$hospital_id} AND (unix_timestamp(now())-b.activity_time <= 1200)";
        $result = M()->query($sql);
        return count($result) == 0 ? '0' : '1';
    }

}
